package poo.listadoppia;

import java.util.*;

public class ListaDoppia<T extends Comparable<? super T>> implements
		Iterable<T> {

	private static class Nodo<E> {
		E info;
		Nodo<E> next, prior;
	}

	private Nodo<T> testa = null;

	public void add(T x) {
		Nodo<T> nw = new Nodo<>();
		nw.info = x;
		if (testa == null || testa.info.compareTo(x) >= 0) {
			nw.prior = null;
			nw.next = testa;
			if (testa != null)
				testa.prior = nw;
			testa = nw;
		} else {
			Nodo<T> cor = testa.next;
			Nodo<T> pre = testa;
			while (cor != null && cor.info.compareTo(x) < 0) {
				pre = cor;
				cor = cor.next;

			}
			nw.next = cor;
			if (cor != null)
				cor.prior = null;
			nw.prior = pre;
			pre.next = nw;
		}// else
	}// add
		// manca size.

	public void remove(T x) {
		Nodo<T> cor = testa;
		while (cor != null && cor.info.compareTo(x) < 0)
			cor = cor.next;
		if (cor != null && cor.info.equals(x)) {
			if (cor == testa) {
				testa = testa.next;
				if (testa != null)
					testa.prior = null;
			} else {
				cor.prior.next = cor.next;
				if (cor.next != null)
					cor.next.prior = cor.prior;
			}// else
		}// if
			// if cor == null elemento non presente

	}// remove

	@Override
	public Iterator<T> iterator() {

		return new Iteratore();
	}

	private class Iteratore implements Iterator<T> {

		private Nodo<T> cor = null;
		private boolean rimuovibile = false;

		@Override
		public boolean hasNext() {
			if (cor == null)
				return testa != null;

			return cor.next != null;
		}

		@Override
		public T next() {

			if (!hasNext())
				throw new NoSuchElementException();

			rimuovibile = true;
			if (cor == null)
				cor = testa;
			else
				cor = cor.next;

			return cor.info;
		}// next

		public void remove() {
			if (!rimuovibile)
				throw new IllegalStateException();
			rimuovibile = false;
			if (cor == testa) {
				testa = testa.next;
				if (testa != null)
					testa.prior = null;
			} else {
				cor.prior.next = cor.next;
				if (cor.next != null)
					cor.next.prior = cor.prior;
			}
			cor = cor.prior;
		}// remove

	}

	public static void main(String[] args) {
		ListaDoppia ld = new ListaDoppia();
		int[] a = { 15, 2, 9, 20, 3, 5, 1 };
		for (int x : a)
			ld.add(x);
	}// main

}// listadoppia
